package com.fms.quartz;

import com.fms.constant.MessageConstant;
import com.fms.job.InitAttendanceJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class SystemSchedulerServiceImpl implements SystemSchedulerService {

    private final Scheduler scheduler;

    @Override
    @Transactional
    public boolean addScheduler(JobDataOfInitAttendance jobDataOfInitAttendance, String name, String group, String cron) {
        try {
            if (!CronExpression.isValidExpression(cron)) {
                return false;
            }
            log.info("开始创建定时器:cron:{},name:{}",cron,name);
            //存储数据
            JobDataMap jobDataMap=new JobDataMap(Map.of(MessageConstant.JOB_MAP_DEPT_IDS, jobDataOfInitAttendance.getDeptIds()
                    , MessageConstant.JOB_MAP_TASK_IDS, jobDataOfInitAttendance.getTaskId()));
            //创建job
            JobDetail jobDetail = JobBuilder.newJob(InitAttendanceJob.class)//绑定一个具体工作类
                    .withIdentity(name, group) //设置一个标识，分组以及名字
                    .usingJobData(jobDataMap)//存储数据
                    .storeDurably(true) // 设置作业为持久化的
                    .build();
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(name, group)//设置一个触发器标识,跟JobDetail使用一样的命名以及分组
                    .forJob(jobDetail)//绑定trigger到jobDetail
                    .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                    .build();
            scheduler.scheduleJob(jobDetail, trigger);
            return true;
        } catch (SchedulerException e) {
            log.info("{}创建添加定时器失败", jobDataOfInitAttendance.getTaskId());
            return false;
        }
    }

    @Override
    @Transactional
    public boolean updateScheduler(String jobDetailName, String jobDetailGroup, String cron, JobDataOfInitAttendance jobDataOfInitAttendance) {
        try {
            if(cron!=null){
                if(!CronExpression.isValidExpression(cron)){
                    return false;
                }
                //triggerKey为添加定时任务时配置的name,group，这里是添加的时候设置的name跟group跟jobDetail是一样的
                TriggerKey triggerKey = TriggerKey.triggerKey(jobDetailName, jobDetailGroup);
                Trigger newTrigger = TriggerBuilder
                        .newTrigger()
                        .withIdentity(triggerKey)
                        .withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
                scheduler.rescheduleJob(triggerKey, newTrigger);
            }

            List<Long> deptIds = jobDataOfInitAttendance.getDeptIds();
            if(deptIds !=null){
                JobKey jobKey = JobKey.jobKey(jobDetailName, jobDetailGroup);
                if (!scheduler.checkExists(jobKey)) {
                    return false;
                }
                // 获取现有的 JobDetail
                JobDetail existingJobDetail = scheduler.getJobDetail(jobKey);

                if (existingJobDetail != null) {
                    // 获取现有的 JobDataMap
                    JobDataMap jobDataMap = existingJobDetail.getJobDataMap();
                    // 修改 JobDataMap 中的数据
                    jobDataMap.put(MessageConstant.JOB_MAP_DEPT_IDS, deptIds);

                    // 创建一个新的 JobDetail，并将修改后的 JobDataMap 设置进去
                    JobDetail newJobDetail = JobBuilder.newJob(existingJobDetail.getJobClass())
                            .withIdentity(existingJobDetail.getKey())
                            .usingJobData(jobDataMap)
                            .storeDurably(true) // 设置作业为持久化的
                            .build();
                    // 调度更新后的 JobDetail
                    scheduler.addJob(newJobDetail, true);
                }
            }
            return true;
        } catch (SchedulerException e) {
            log.info("更新名为{}，组为{}的定时器失败",jobDetailName,jobDetailGroup);
            return false;
        }
    }


    @Override
    @Transactional
    public boolean deleteScheduler(String jobDetailName, String jobDetailGroup) {
        try {
            JobKey jobKey = JobKey.jobKey(jobDetailName, jobDetailGroup);
            if (!scheduler.checkExists(jobKey)) {
                return false;
            }
            scheduler.deleteJob(jobKey);
            return true;
        } catch (SchedulerException e) {
            log.info("删除名为{}，组为{}的定时器失败",jobDetailName,jobDetailGroup);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean pauseScheduler(String jobDetailName, String jobDetailGroup) {
        try {
            JobKey jobKey = JobKey.jobKey(jobDetailName, jobDetailGroup);
            if (!scheduler.checkExists(jobKey)) {
                return false;
            }
            scheduler.pauseJob(jobKey);
            return true;
        } catch (SchedulerException e) {
            log.info("禁用名为{}，组为{}的定时器失败",jobDetailName,jobDetailGroup);
            return false;
        }
    }

    @Override
    public boolean resumeScheduler(String jobDetailName, String jobDetailGroup) {
        try {
            JobKey jobKey = JobKey.jobKey(jobDetailName, jobDetailGroup);
            if (!scheduler.checkExists(jobKey)) {
                return false;
            }
            scheduler.resumeJob(jobKey);
            return true;
        } catch (SchedulerException e) {
            log.info("恢复名为{}，组为{}的定时器失败",jobDetailName,jobDetailGroup);
            return false;
        }
    }

    //查看所有定时器
    @Override
    public void getAllJobKeys() {
        // 获取所有 JobDetail
        try {
            log.info("开始获取所有定时器");
            boolean flag=true;
            for (String groupName : scheduler.getJobGroupNames()) {
                for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
                    JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                    List<? extends Trigger> triggersOfJob = scheduler.getTriggersOfJob(jobKey);
                    CronTrigger cronTrigger = (CronTrigger) triggersOfJob.get(0);
                    flag=false;
                    log.info("Job Key: {}" ,jobKey);
                    log.info("Job Detail: {}" , jobDetail);
                    log.info("Job triggersOfJob: {},{}" , cronTrigger.getNextFireTime(), cronTrigger.getCronExpression());
                }
            }
            if(flag){
                log.info("没有定义任何定时器");
            }
        } catch (SchedulerException e) {
            log.info("Error while retrieving job details: {}" , e.getMessage());
        }
    }

}